﻿using Autofac;
using AutoMapper;
using Dapper;
using IdGen;
using KWT.DRG_DIP.API.Infrastructure;
using KWT.DRG_DIP.Common;
using KWT.DRG_DIP.DB;
using KWT.DRG_DIP.DO.Group;
using KWT.DRG_DIP.DO.Group.DIPGroup;
using KWT.DRG_DIP.DO.System;
using KWT.DRG_DIP.DTO.Group;
using KWT.DRG_DIP.DTO.Settlement.List;
using KWT.DRG_DIP.DTO.Settlement.Quota;
using KWT.DRG_DIP.ISvc;
using KWT.DRG_DIP.PO.Basic;
using KWT.DRG_DIP.PO.QC;
using KWT.DRG_DIP.PO.Settlement;
using KWT.DRG_DIP.Svc;
using KWT.DRG_DIP.Svc.Group.DIPGroup;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NetTopologySuite.Index.HPRtree;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq.Dynamic.Core;


namespace KWT.DRG_DIP.API.Controllers.Settlement
{
    /// <summary>
    /// 结算清单
    /// </summary>
    [ApiExplorerSettings(GroupName = "settlement")]
    [AllowAnonymous]
    public class ListController : SettlementControllerBase
    {
        public EFContext ef { get; set; }

        private readonly IComponentContext componentContext;
        public IDipGrouperSvc dipGrouperSvc { get; set; }
        public IDrgGrouperSvc drgGrouperSvc { get; set; }

        public ListController(IComponentContext _componentContext)
        {
            componentContext = _componentContext;
        }

        #region 添加或编辑
        /// <summary>
        /// 添加或编辑
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<string>), 200)]
        public async Task<OutputResult> AddOrUpdate(InAddOrUpdate dto)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];

            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("请求头缺少租户编码（TenantID）");
            }

            var tenant = main.Find<Sys_Tenant>(tenantID);

            if (tenant == null)
            {
                return Fail("租户不存在");
            }
            var quotaSvc = componentContext.ResolveNamed<IQuotaSvc>(tenant.UsePolicy);

            bool flag = false;
            string id;
            if (string.IsNullOrWhiteSpace(dto.Head.ListID))
            {
                if (dto.DiagInfo.DiagItems.Count(x => x.Type == 1 && x.Way == 1) != 1)
                {
                    return Fail("主诊断有且只有1个");
                }
                //上传截止日期
                var uploadDay = ef.Set<Sys_Enum>().Single(x => x.Group == "上传时间").Value;
                var uploadDate = new DateTime(DateTime.Now.Year, DateTime.Now.AddMonths(1).Month, Convert.ToInt32(uploadDay) + 1);
                //医保结算清单
                var sysList = new Sys_List()
                {
                    ListID = "SL" + snow_id.CreateId().ToString(),
                    HospitalName = dto.Head.HospitalName,
                    HospitalCode = dto.Head.HospitalCode,
                    Level = dto.Head.Level,
                    InsureCode = dto.Head.InsureCode,
                    Number = dto.Head.Number,
                    DeclareTime = dto.Head.DeclareTime,
                    AreaID = "",
                    Abnormal = dto.Extra.Abnormal,
                    CategoryID = dto.Extra.CategoryID,
                    CategoryName = dto.Extra.CategoryName,
                    Group_Code = dto.Extra.Group_Code,
                    Group_Name = dto.Extra.Group_Name,
                    Assist_Type = dto.Extra.Assist_Type,
                    Assist_Name = dto.Extra.Assist_Name,
                    Assist_Code = dto.Extra.Assist_Code,
                    Diag_Code = dto.DiagInfo.DiagItems.SingleOrDefault(x => x.Type == 1 && x.Way == 1).Code,
                    Diag_Name = dto.DiagInfo.DiagItems.SingleOrDefault(x => x.Type == 1 && x.Way == 1).Name,
                    Oper_Code = dto.DiagInfo.OperItems.Count(x => x.Type == 1) > 0 ? dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1).OperCode : "",
                    Oper_Name = dto.DiagInfo.OperItems.Count(x => x.Type == 1) > 0 ? dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1).OperName : "",
                    CardNo = dto.Head.CardNo,
                    UploadEndTime = uploadDate
                };
                await ef.AddAsync(sysList);

                //质控信息，先删除，再新增
                await ef.Set<QC_Err_Item>().Where(x => x.ListID == sysList.ListID).ExecuteDeleteAsync();
                var qcList = _mapper.Map<List<QC_Err_Item>>(dto.QCInfos);
                qcList.ForEach(x => { x.ListID = sysList.ListID; x.QIID = "QI" + snow_id.CreateId().ToString(); });
                await ef.AddRangeAsync(qcList);

                //指标
                var inputQuota = new InSetQuota()
                {
                    GroupCode = dto.Extra.Group_Code,
                    InDays = dto.DiagInfo.InDays,
                    InsureType = dto.BasicInfo.InsureType,
                    ListID = sysList.ListID,
                    OutWay = dto.DiagInfo.OutWay,
                    Policy = tenant.UsePolicy,
                    Total = dto.ChargeInfo.Total
                };
                var quota = quotaSvc.SetQuota(inputQuota);
                sysList.Mag = quota.mag;
                sysList.MagType = quota.magType;

                await ef.AddAsync(sysList);
                var basic = _mapper.Map<List_BasicInfo>(dto.BasicInfo);
                basic.ListID = sysList.ListID;
                await ef.AddAsync(basic);

                var special = _mapper.Map<List<List_SepcialDiagInfo>>(dto.SpecialDiagInfos);
                special.ForEach(x => { x.ListID = sysList.ListID; x.SDID = "SD" + snow_id.CreateId().ToString(); });

                await ef.AddRangeAsync(special);

                var diag = _mapper.Map<List_DiagInfo>(dto.DiagInfo);
                diag.DIID = "DI" + snow_id.CreateId().ToString();
                diag.ListID = sysList.ListID;
                await ef.AddAsync(diag);

                var diag_item = _mapper.Map<List<DiagInfo_Item>>(dto.DiagInfo.DiagItems);
                diag_item.ForEach(x => { x.ListID = sysList.ListID; x.DIID = "DI" + snow_id.CreateId().ToString(); });
                await ef.AddRangeAsync(diag_item);

                var oper_item = _mapper.Map<List<DiagInfo_OperItem>>(dto.DiagInfo.OperItems);
                oper_item.ForEach(x => { x.ListID = sysList.ListID; x.DOID = "DO" + snow_id.CreateId().ToString(); });
                await ef.AddRangeAsync(oper_item);

                var person = _mapper.Map<List_PersonInfo>(dto.PersonInfo);
                person.LPID = "LP" + snow_id.CreateId().ToString();
                person.ListID = sysList.ListID;
                await ef.AddAsync(person);

                var charge = _mapper.Map<List_ChargeInfo>(dto.ChargeInfo);
                charge.ListID = sysList.ListID;
                charge.ChargeID = "CG" + snow_id.CreateId().ToString();
                charge.Remain = quota.jy;
                await ef.AddAsync(charge);

                var charge_item = _mapper.Map<List<ChargeInfo_Item>>(dto.ChargeInfo.Items);
                charge_item.ForEach(x => { x.ListID = sysList.ListID; x.CIID = "CI" + snow_id.CreateId().ToString(); });
                await ef.AddRangeAsync(charge_item);

                //预分组插件-推荐信息:根据患者证件号码查找
                var suggest = ef.Set<List_Suggest>().SingleOrDefault(x => x.CertNo == basic.CertNo && x.ListID == "");
                if (suggest != null)
                {
                    suggest.ListID = sysList.ListID;
                    ef.Update(suggest);
                }

                flag = await ef.SaveChangesAsync() > 0;

                id = sysList.ListID;


            }
            else
            {
                try
                {
                    using var tran = await ef.Database.BeginTransactionAsync();
                    var sysList = await ef.FindAsync<Sys_List>(dto.Head.ListID);
                    if (sysList == null)
                    {
                        return Fail("未找到该项！");
                    }
                    sysList.HospitalName = dto.Head.HospitalName;
                    sysList.HospitalCode = dto.Head.HospitalCode;
                    sysList.Level = dto.Head.Level;
                    sysList.InsureCode = dto.Head.InsureCode;
                    sysList.Number = dto.Head.Number;
                    sysList.DeclareTime = dto.Head.DeclareTime;
                    sysList.Diag_Code = dto.DiagInfo.DiagItems.SingleOrDefault(x => x.Type == 1 && x.Way == 1).Code;
                    sysList.Diag_Name = dto.DiagInfo.DiagItems.SingleOrDefault(x => x.Type == 1 && x.Way == 1).Name;
                    sysList.Abnormal = dto.Extra.Abnormal;
                    sysList.CategoryID = dto.Extra.CategoryID;
                    sysList.CategoryName = dto.Extra.CategoryName;
                    sysList.Group_Code = dto.Extra.Group_Code;
                    sysList.Group_Name = dto.Extra.Group_Name;
                    sysList.Assist_Type = dto.Extra.Assist_Type;
                    sysList.Assist_Name = dto.Extra.Assist_Name;
                    sysList.Assist_Code = dto.Extra.Assist_Code;
                    sysList.Oper_Code = dto.DiagInfo.OperItems.Count(x => x.Type == 1) > 0 ? dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1).OperCode : "";
                    sysList.Oper_Name = dto.DiagInfo.OperItems.Count(x => x.Type == 1) > 0 ? dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1).OperName : "";
                    sysList.CardNo = dto.Head.CardNo;
                    if (dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1) != null)
                    {
                        sysList.Oper_Code = dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1).OperCode;
                        sysList.Oper_Name = dto.DiagInfo.OperItems.SingleOrDefault(x => x.Type == 1).OperName;
                    }


                    //指标
                    var inputQuota = new InSetQuota()
                    {
                        GroupCode = dto.Extra.Group_Code,
                        InDays = dto.DiagInfo.InDays,
                        InsureType = dto.BasicInfo.InsureType,
                        ListID = sysList.ListID,
                        OutWay = dto.DiagInfo.OutWay,
                        Policy = tenant.UsePolicy,
                        Total = dto.ChargeInfo.Total
                    };
                    var quota = quotaSvc.SetQuota(inputQuota);
                    sysList.Mag = quota.mag;
                    sysList.MagType = quota.magType;
                    sysList.Flag = 1;
                    ef.Set<Sys_List>().Attach(sysList);
                    var basic = _mapper.Map<List_BasicInfo>(dto.BasicInfo);
                    ef.Update(basic);

                    await ef.Set<QC_Err_Item>().Where(x => x.ListID == dto.Head.ListID).ExecuteDeleteAsync();
                    var qcList = _mapper.Map<List<QC_Err_Item>>(dto.QCInfos);
                    qcList.ForEach(x => x.QIID = "QI" + snow_id.CreateId().ToString());
                    await ef.AddRangeAsync(qcList);

                    var special = _mapper.Map<List<List_SepcialDiagInfo>>(dto.SpecialDiagInfos);
                    var _special = await ef.Set<List_SepcialDiagInfo>().Where(x => x.ListID == dto.Head.ListID).ExecuteDeleteAsync();
                    await ef.AddRangeAsync(special);

                    var diag = _mapper.Map<List_DiagInfo>(dto.DiagInfo);
                    ef.Update(diag);

                    var diag_item = _mapper.Map<List<DiagInfo_Item>>(dto.DiagInfo.DiagItems);
                    diag_item.ForEach(x => x.DIID = "DI" + snow_id.CreateId().ToString());
                    var _diag_item = await ef.Set<DiagInfo_Item>().Where(x => x.ListID == dto.Head.ListID).ExecuteDeleteAsync();

                    await ef.AddRangeAsync(diag_item);

                    var oper_item = _mapper.Map<List<DiagInfo_OperItem>>(dto.DiagInfo.OperItems);
                    oper_item.ForEach(x => x.DOID = "DO" + snow_id.CreateId().ToString());
                    var _oper_item = await ef.Set<DiagInfo_OperItem>().Where(x => x.ListID == dto.Head.ListID).ExecuteDeleteAsync();
                    await ef.AddRangeAsync(oper_item);

                    var charge = _mapper.Map<List_ChargeInfo>(dto.ChargeInfo);
                    charge.Remain = quota.jy;
                    ef.Update(charge);

                    var person = _mapper.Map<List_PersonInfo>(dto.PersonInfo);
                    ef.Update(person);

                    var charge_item = _mapper.Map<List<ChargeInfo_Item>>(dto.ChargeInfo.Items);
                    charge_item.ForEach(x => { x.CIID = "CI" + snow_id.CreateId().ToString(); x.ListID = dto.Head.ListID; });
                    var _charge_item = await ef.Set<ChargeInfo_Item>().Where(x => x.ListID == dto.Head.ListID).ExecuteDeleteAsync();
                    await ef.AddRangeAsync(charge_item);

                    //预分组插件-推荐信息:根据患者证件号码查找
                    var suggest = ef.Set<List_Suggest>().SingleOrDefault(x => x.CertNo == basic.CertNo && x.ListID == "");
                    if (suggest != null)
                    {
                        suggest.ListID = sysList.ListID;
                        ef.Update(suggest);
                    }

                    await tran.CommitAsync();

                    flag = await ef.SaveChangesAsync() > 0;
                    id = sysList.ListID;
                    return Output(flag, "操作成功", "操作失败", id);
                }
                catch (Exception e)
                {
                    _Log.WriteError(e.Message);
                    return Output(false, "操作成功", "操作失败");
                }

            }
            return Output(flag, "操作成功", "操作失败");
        }

        #endregion

        #region 医保结算清单详情
        /// <summary>
        /// 医保结算清单详情
        /// </summary>
        /// <param name="listID">医保结算清单ID</param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<OutDetail>), 200)]
        public OutputResult Detail([FromQuery] string listID)
        {
            var sysList = ef.Find<Sys_List>(listID);
            if (sysList == null)
            {
                return Fail("未找到该项！");
            }
            //医保结算清单（基本信息）
            var basic_info = ef.Find<List_BasicInfo>(listID);

            //医疗收费信息
            var charge_info = ef.Find<List_ChargeInfo>(listID);
            var charge_item = ef.Set<ChargeInfo_Item>().Where(x => x.ListID == listID).AsNoTracking().ToList();
            var ci = _mapper.Map<ChargeInfo>(charge_info);
            ci.Items = _mapper.Map<List<ChargeInfoItem>>(charge_item);

            //医保结算清单（住院诊疗信息）
            var diag_info = ef.Set<List_DiagInfo>().AsNoTracking().SingleOrDefault(x => x.ListID == listID);
            var di = _mapper.Map<DiagInfo>(diag_info);

            //住院诊疗信息（中西医诊断列表）
            var diagItem = ef.Set<DiagInfo_Item>().Where(x => x.ListID == listID).AsNoTracking().ToList();
            var diagItems = _mapper.Map<List<DiagInfoItem>>(diagItem);
            di.DiagItems = diagItems;

            //住院诊疗信息（手术信息）
            var operItem = ef.Set<DiagInfo_OperItem>().Where(x => x.ListID == listID).AsNoTracking().ToList();
            var operItems = _mapper.Map<List<DiagInfoOperItem>>(operItem);
            di.OperItems = operItems;

            //医保结算清单（慢特病诊疗信息）
            var special = ef.Set<List_SepcialDiagInfo>().Where(x => x.ListID == listID).AsNoTracking().ToList();
            var specialInfo = _mapper.Map<List<SpecialDiagInfo>>(special);

            //清单-相关医生护士
            var person = ef.Set<List_PersonInfo>().AsNoTracking().SingleOrDefault(x => x.ListID == listID);
            var personInfo = _mapper.Map<PersonInfo>(person);

            //预分组插件-推荐信息:根据清单ID先查找，如果没有对应，则根据患者证件号码查找
            var suggest = ef.Set<List_Suggest>().SingleOrDefault(x => x.ListID == listID);
            if (suggest == null)
            {
                suggest = ef.Set<List_Suggest>().SingleOrDefault(x => x.CertNo == basic_info.CertNo);
            }
            var suggestInfo = _mapper.Map<SuggestInfo>(suggest);

            var enumList = ef.Set<Sys_Enum>().Where(x => x.Group == "卫统4").AsNoTracking();
            var qcInfo = (from x in ef.Set<QC_Err_Item>()
                          join y in ef.Set<Sys_QC_Err>() on x.ErrCode equals y.ErrCode
                          join z in enumList on x.Property equals z.Value
                          where x.ListID == listID
                          select new QCInfo() { ErrCode = x.ErrCode, ListID = x.ListID, Property = x.Property, Msg = y.Msg, QIID = x.QIID, PropertyName = z.Text }).ToList();

            var detail = new OutDetail()
            {
                Head = new Head()
                {
                    DeclareTime = sysList.DeclareTime,
                    HospitalCode = sysList.HospitalCode,
                    HospitalName = sysList.HospitalName,
                    InsureCode = sysList.InsureCode,
                    Level = sysList.Level,
                    Number = sysList.Number,
                    CardNo = sysList.CardNo,
                    ListID = sysList.ListID,
                },
                BasicInfo = _mapper.Map<BasicInfo>(basic_info),
                ChargeInfo = ci,
                DiagInfo = di,
                SpecialDiagInfos = specialInfo,
                PersonInfo = personInfo,
                Extra = new Extra() { Abnormal = sysList.Abnormal, CategoryID = sysList.CategoryID, CategoryName = sysList.CategoryName },
                SuggestInfo = suggestInfo,
                QCInfos = qcInfo
            };
            return Output(true, "", "", detail);
        }
        #endregion

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(PageList<OutPageList>), 200)]
        public OutputResult PageList(InPageList dto)
        {
            var q1 = ef.Set<Sys_List>().AsQueryable();
            var q2 = ef.Set<List_BasicInfo>().AsQueryable();
            var q3 = ef.Set<List_PersonInfo>().AsQueryable();
            var q4 = ef.Set<List_DiagInfo>().AsQueryable();
            var q5 = ef.Set<List_ChargeInfo>().AsQueryable();

            if (!string.IsNullOrEmpty(dto.RealName))
            {
                q2 = q2.Where(x => EF.Functions.Like(x.RealName, $"%{dto.RealName}%"));
            }
            if (!string.IsNullOrEmpty(dto.PinYin))
            {
                q2 = q2.Where(x => EF.Functions.Like(x.PinYin, $"%{dto.PinYin}%"));
            }

            var user = CurrentUser;

            var q = from x in q1
                    join y in q2
                    on x.ListID equals y.ListID
                    join z in q3
                    on x.ListID equals z.ListID
                    join a in q4
                    on x.ListID equals a.ListID
                    join b in q5
                    on x.ListID equals b.ListID
                    where string.IsNullOrEmpty(dto.HospitalCode) || x.HospitalCode == dto.HospitalCode
                    && (dto.CategoryID.Length == 0 || dto.CategoryID.Contains(x.CategoryID))
                    && (dto.UploadStatus == 0 || x.UploadStatus == dto.UploadStatus)
                    && (dto.CheckStatus == 0 || x.CheckStatus == dto.CheckStatus)
                    && (dto.Flag == 0 || x.Flag == dto.Flag)
                    && (dto.MagType == 0 || x.MagType == dto.MagType)
                    && (string.IsNullOrEmpty(dto.Coder) || z.BMY == dto.Coder)
                    && (user.IsAuth || user.CategoryIDs.Contains(x.CategoryID))
                    && (string.IsNullOrEmpty(dto.AreaID) || user.AreaIDs.Contains(x.AreaID))
                    select new OutPageList()
                    {
                        Abnormal = x.Abnormal,
                        ListID = x.ListID,
                        CheckStatus = x.CheckStatus,
                        Coder = z.BMY,
                        CategoryName = x.CategoryName,
                        Diag_Code = x.Diag_Code,
                        Diag_Name = x.Diag_Name,
                        Doctor = z.DcName,
                        Flag = x.Flag,
                        InDays = a.InDays,
                        Mag = x.Mag,
                        MagType = x.MagType,
                        Number = x.Number,
                        Oper_Code = x.Oper_Code,
                        Oper_Name = x.Oper_Name,
                        OutDate = x.OutDate,
                        QDLSH = x.QDLSH,
                        SettleDate = x.SettleDate,
                        Sex = y.Sex,
                        TotalFee = b.Total,
                        UploadEndTime = x.UploadEndTime,
                        RealName = y.RealName,
                        Group_Code = x.Group_Code,
                        Group_Name = x.Group_Name,
                        InsureType = y.InsureType,
                        Remain = b.Remain,
                        CheckBy = x.CheckBy,
                    };
            if (!string.IsNullOrEmpty(dto.Col) && !string.IsNullOrEmpty(dto.Sort))
            {
                if (dto.Sort.Equals("normal"))
                {
                    q = q.OrderBy($"{dto.Col} asc");
                }
                else { q = q.OrderBy($"{dto.Col} {dto.Sort}"); }

            }
            int total = q.Count();
            var list = q.AsNoTracking().ToPageList(dto.PageNo, dto.PageSize);
            return Output(list != null, "", "", new PageList<OutPageList>() { List = list, Total = total });
        }
        /// <summary>
        /// 二级审核-待办事项-左侧数据
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<OutLeftData>), 200)]
        public OutputResult LeftData()
        {
            int qds = ef.Set<Sys_List>().Count(x => x.UploadStatus == -1);
            int dsh = ef.Set<Sys_List>().Count(x => x.CheckStatus == 0);
            int ljsc = ef.Set<Sys_List>().Count(x => EF.Functions.DateDiffDay(DateTime.Now, x.UploadEndTime) < 7);
            int ccsc = ef.Set<Sys_List>().Count(x => EF.Functions.DateDiffDay(DateTime.Now, x.UploadEndTime) >= 7);
            int shyc = ef.Set<Sys_List>().Count(x => x.CheckStatus == -1);
            var hm_code = ef.Set<Sys_PolicyEnum>().Where(x => x.Group == "主诊断" && x.Extra1 == "1").Select(x => x.Code1).AsNoTracking().ToList();
            int sshm = ef.Set<Sys_List>().Count(x => hm_code.Contains(x.Group_Code));
            string sql = @"SELECT count(distinct c.ListID) FROM `sys_qc_err` a
inner join qc_err_item b on a.ErrCode=b.ErrCode
INNER JOIN sys_list c on c.ListID=b.ListID";
            int bpp = Convert.ToInt32(dapper.ExecuteScalar(sql));
            var data = new OutLeftData()
            {
                bpp = bpp,
                ccsc = ccsc,
                dsh = dsh,
                ljsc = ljsc,
                qds = qds,
                shyc = shyc,
                sshm = sshm
            };
            return Output(true, "", "", data);
        }

        /// <summary>
        /// 二级审核-待办事项-右侧数据
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutRightData>), 200)]
        public OutputResult RightData(InRightData dto)
        {
            int total = ef.Set<Sys_List>().Count();
            var q1 = ef.Set<Sys_List>().AsQueryable();
            var q2 = ef.Set<List_PersonInfo>().AsQueryable();
            var q3 = ef.Set<List_BasicInfo>().AsQueryable();

            var q = (from x in q1
                     join y in q2 on x.ListID equals y.ListID
                     join z in q3 on x.ListID equals z.ListID
                     where string.IsNullOrEmpty(dto.CategoryID) || x.CategoryID == dto.CategoryID
                     && (string.IsNullOrEmpty(dto.DcName) || y.DcName == dto.DcName)
                     && (dto.InsureType == 0 || z.InsureType == dto.InsureType)
                     && (string.IsNullOrEmpty(dto.StartDate) || x.OutDate >= Convert.ToDateTime(dto.StartDate))
                     && (string.IsNullOrEmpty(dto.EndDate) || x.OutDate <= Convert.ToDateTime(dto.EndDate))
                     select x);

            int wsc = q.Count(x => x.UploadStatus == 0);
            int sccg = q.Count(x => x.UploadStatus == 1);
            int scsb = q.Count(x => x.UploadStatus == -1);

            string sql = @"select count(*) data,UploadStatus,DATE_FORMAT(UploadEndTime, '%Y-%m') fmt_date,
CASE UploadStatus WHEN 1 THEN '上传成功数' 
WHEN 0 THEN '未上传数' 
WHEN -1 THEN '上传失败数' ELSE '' 
END as name
from sys_list  a 
inner join list_personinfo b on a.ListID=b.ListID
inner join list_basicinfo c on a.ListID=c.ListID
inner join list_diaginfo d on a.ListID=d.ListID
where 0=0";
            if (!string.IsNullOrEmpty(dto.CategoryID))
            {
                sql += @" and a.CategoryID=@CategoryID";
            }
            if (!string.IsNullOrEmpty(dto.DcName))
            {
                sql += @" and b.DcName=@DcName";
            }
            if (dto.InsureType > 0)
            {
                sql += @" and c.InsureType=@InsureType";
            }
            if (!string.IsNullOrEmpty(dto.StartDate) && !string.IsNullOrEmpty(dto.EndDate))
            {
                sql += @" and d.outTime >=@StartDate and d.outTime<=@EndDate";
            }
            sql += @" GROUP BY UploadStatus,DATE_FORMAT(UploadEndTime, '%Y-%m') order by fmt_date,UploadStatus desc";

            var list = dapper.Select<dynamic>(sql, new { dto.CategoryID, dto.DcName, dto.InsureType, dto.StartDate, dto.EndDate });

            int zbls = q.Count();
            int dsh = q.Count(x => x.CheckStatus == 0);
            int ysh = q.Count(x => x.CheckStatus == 1);

            string sql1 = @"select  count(distinct c.ListID) data,b.Msg name from qc_err_item a 
inner join sys_qc_err b on a.ErrCode=b.ErrCode
inner join sys_list c on c.ListID=a.ListID 
inner join list_personinfo d on c.ListID=d.ListID
inner join list_basicinfo e on c.ListID=e.ListID
where 0=0";
            if (!string.IsNullOrEmpty(dto.CategoryID))
            {
                sql1 += @" and c.CategoryID=@CategoryID";
            }
            if (!string.IsNullOrEmpty(dto.DcName))
            {
                sql1 += @" and d.DcName=@DcName";
            }
            if (dto.InsureType > 0)
            {
                sql1 += @" and e.InsureType=@InsureType";
            }
            if (!string.IsNullOrEmpty(dto.StartDate) && !string.IsNullOrEmpty(dto.EndDate))
            {
                sql1 += @" and c.outDate >=@StartDate and c.outDate <=@EndDate";
            }
            sql1 += @" group by b.Msg order by data desc limit 10";

            var list1 = dapper.Select<dynamic>(sql1, new { dto.CategoryID, dto.DcName, dto.InsureType });

            var series = new List<Series>
            {
                new() { name = "上传成功数", data = [.. list.Where(x => x.name == "上传成功数").Select(x => x.data).Cast<long>()], type = "line", stack = "Total" },
                new() { name = "未上传数", data = [.. list.Where(x => x.name == "未上传数").Select(x => x.data).Cast<long>()], type = "line", stack = "Total" },
                new() { name = "上传失败数", data = [.. list.Where(x => x.name == "上传失败数").Select(x => x.data).Cast<long>()], type = "line", stack = "Total" }
            };
            var series1 = new List<Series>
            {
                new() { name = "", data = [.. list1.Select(x => x.data).Cast<long>()], type = "bar", stack = "" }
            };
            var result = new OutRightData()
            {
                Total = total,
                wsc = wsc,
                sccg = sccg,
                scsb = scsb,
                Line = new ECharts_Line()
                {
                    xAxis = [.. list.Select(x => x.fmt_date).Cast<string>().Distinct()],
                    legend = ["上传成功数", "未上传数", "上传失败数"],
                    Series = series,
                },
                dsh = dsh,
                ysh = ysh,
                zbls = zbls,
                Bar = new Echarts_Bar()
                {
                    yAxis = [.. list1.Select(x => x.name).Cast<string>()],
                    Series = series1
                }
            };
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 清单总览
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutOverview>), 200)]
        public OutputResult Overview(InOverview dto)
        {
            var q1 = ef.Set<Sys_List>().AsQueryable();
            var q2 = ef.Set<List_PersonInfo>().AsQueryable();
            var q3 = ef.Set<List_BasicInfo>().AsQueryable();

            var q = (from x in q1
                     join y in q2 on x.ListID equals y.ListID
                     join z in q3 on x.ListID equals z.ListID
                     where string.IsNullOrEmpty(dto.AreaID) || x.AreaID == dto.AreaID
                     && (dto.CategoryID.Length <= 0 || dto.CategoryID.Contains(x.CategoryID))
                     && (string.IsNullOrEmpty(dto.StartOutDate) || x.OutDate >= Convert.ToDateTime(dto.StartOutDate))
                     && (string.IsNullOrEmpty(dto.EndOutDate) || x.OutDate <= Convert.ToDateTime(dto.EndOutDate))
                     && (string.IsNullOrEmpty(dto.StartSettleDate) || x.SettleDate >= Convert.ToDateTime(dto.StartSettleDate))
                     && (string.IsNullOrEmpty(dto.EndSettleDate) || x.SettleDate <= Convert.ToDateTime(dto.EndSettleDate))
                     select x);
            int total = q.Count(x => x.OutDate <= DateTime.Now);
            int ytj = q.Count(x => x.CheckStatus == 0);
            int ysc = q.Count(x => x.CheckStatus == 1);

            var e1 = ef.Set<Sys_QC_Err>().AsQueryable();
            var e2 = ef.Set<QC_Err_Item>().AsQueryable();
            var e = from x1 in e1
                    join y1 in e2 on x1.ErrCode equals y1.ErrCode
                    select x1;

            int fbmqx = e.Count(x => x.IsCodeErr == false);
            int bmqx = e.Count(x => x.IsCodeErr == true);
            int yrz = q.Count(x => x.Group_Code != "" || x.Group_Code != "0000");
            int ysh = q.Count(x => x.CheckStatus == 1);
            int ysc1 = q.Count(x => x.UploadStatus == 1);

            string sql1 = "select count(*) data,DATE_FORMAT(CreateDate, '%Y-%m') fmt_date from sys_list a where OutDate<=now()";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql1 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql1 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql1 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql1 += " and CategoryID in (@CategoryID)";
            }
            sql1 += " GROUP BY fmt_date order by fmt_date";
            var list1 = dapper.Select<dynamic>(sql1, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });

            string sql2 = "select count(*) data,DATE_FORMAT(CreateDate, '%Y-%m') fmt_date from sys_list a where CheckStatus=0";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql2 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql2 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql2 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql2 += " and CategoryID in (@CategoryID)";
            }
            sql2 += " GROUP BY DATE_FORMAT(CreateDate, '%Y-%m') order by fmt_date";
            var list2 = dapper.Select<dynamic>(sql2, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });

            string sql3 = "select count(*) data,DATE_FORMAT(CreateDate, '%Y-%m') fmt_date from sys_list a where CheckStatus=1";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql3 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql3 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql3 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql3 += " and CategoryID in (@CategoryID)";
            }
            sql3 += " GROUP BY fmt_date order by fmt_date";
            var list3 = dapper.Select<dynamic>(sql3, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });


            var series1 = new List<Series>
            {
                new() { name = "患者总数", data = [.. list1.Select(x => x.data).Cast<long>()], type = "line", stack = "Total" },
                new() { name = "已提交病案数", data = [.. list2.Select(x => x.data).Cast<long>()], type = "line", stack = "Total" },
                new() { name = "已生成清单数", data = [.. list3.Select(x => x.data).Cast<long>()], type = "line", stack = "Total" }
            };


            var line1 = new ECharts_Line()
            {
                legend = ["患者总数", "已提交病案数", "已生成清单数"],
                xAxis = [.. list1.Select(x => x.fmt_date).Cast<string>().Distinct()],
                Series = series1,
            };


            string sql4 = @"select  count(distinct c.ListID) data,DATE_FORMAT(CreateDate, '%Y-%m') fmt_date from qc_err_item a 
inner join sys_qc_err b on a.ErrCode=b.ErrCode
inner join sys_list c on c.ListID=a.ListID
where b.isCodeErr=0";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql4 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql4 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql4 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql4 += " and CategoryID in (@CategoryID)";
            }
            sql4 += @" group by fmt_date order by fmt_date";
            var list4 = dapper.Select<dynamic>(sql4, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });


            string sql5 = @"select  count(distinct c.ListID) data,DATE_FORMAT(CreateDate, '%Y-%m') fmt_date from qc_err_item a 
inner join sys_qc_err b on a.ErrCode=b.ErrCode
inner join sys_list c on c.ListID=a.ListID
where b.isCodeErr=1";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql5 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql5 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql5 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql5 += " and CategoryID in (@CategoryID)";
            }
            sql5 += @" group by fmt_date order by fmt_date";
            var list5 = dapper.Select<dynamic>(sql5, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });

            string sql6 = @"select  count(1) data,DATE_FORMAT(CreateDate, '%Y-%m') fmt_date from sys_list where Group_Code!='' and Group_Code!='0000'";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql6 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql6 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql6 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql6 += " and CategoryID in (@CategoryID)";
            }
            sql6 += @" group by fmt_date order by fmt_date";
            var list6 = dapper.Select<dynamic>(sql6, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });

            var series2 = new List<Series>
            {
                new() { name = "非编码缺陷数", data = [.. list4.Select(x => x.data).Cast<long>()], type = "line", stack = "Total" },
                new() { name = "编码缺陷数", data = [.. list5.Select(x => x.data).Cast<long>()], type = "line", stack = "Total" },
                new() { name = "已入组清单数", data = [.. list6.Select(x => x.data).Cast<long>()], type = "line", stack = "Total" }
            };


            var line2 = new ECharts_Line()
            {
                legend = ["非编码缺陷数", "编码缺陷数", "已入组清单数"],
                xAxis = [.. list4.Select(x => x.fmt_date).Cast<string>().Distinct()],
                Series = series2,
            };

            string sql7 = @"select count(1) value,Msg label from sys_qc_err a
inner join qc_err_item b on a.ErrCode=b.ErrCode
inner join sys_list c on c.ListID=b.ListID
where IsCodeErr=1";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql7 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql7 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql7 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql7 += " and CategoryID in (@CategoryID)";
            }
            sql7 += " GROUP BY Msg order by value desc";
            var list7 = dapper.Select<Top>(sql7, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });

            string sql8 = @"select count(1) value,Msg label from sys_qc_err a
inner join qc_err_item b on a.ErrCode=b.ErrCode
inner join sys_list c on c.ListID=b.ListID
where IsCodeErr=0";
            if (!string.IsNullOrEmpty(dto.StartOutDate) && !string.IsNullOrEmpty(dto.EndOutDate))
            {
                sql8 += " and OutDate>=@StartOutDate and OutDate<=@EndOutDate";
            }
            if (!string.IsNullOrEmpty(dto.StartSettleDate) && !string.IsNullOrEmpty(dto.EndSettleDate))
            {
                sql8 += " and SettleDate>=@StartSettleDate and SettleDate<=@EndSettleDate";
            }
            if (!string.IsNullOrEmpty(dto.AreaID))
            {
                sql8 += " and AreaID=@AreaID";
            }
            if (dto.CategoryID.Length > 0)
            {
                sql8 += " and CategoryID in (@CategoryID)";
            }
            sql8 += " GROUP BY Msg order by value desc";
            var list8 = dapper.Select<Top>(sql8, new { dto.StartOutDate, dto.EndOutDate, dto.StartSettleDate, dto.EndSettleDate, dto.AreaID, dto.CategoryID });
            var result = new OutOverview()
            {
                total = total,
                ytj = ytj,
                ysc = ysc,
                fbmqx = fbmqx,
                bmqx = bmqx,
                yrz = yrz,
                ysh = ysh,
                ysc1 = ysc1,
                Line1 = line1,
                Line2 = line2,
                Top1 = [.. list7],
                Top2 = [.. list8]
            };
            return Output(true, "", "", result);
        }

        /// <summary>
        /// 审核/驳回
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public OutputResult Check(InCheck dto)
        {
            var list = ef.Find<Sys_List>(dto.ListID);
            if (list == null)
            {
                return Fail("该项不存在");
            }
            var user = CurrentUser;
            list.CheckStatus = dto.Status;
            list.CheckBy = user.RealName;
            ef.Attach(list);
            var item = new List_CheckItem()
            {
                LCID = "LC" + snow_id.CreateId().ToString(),
                ListID = dto.ListID,
                Memo = dto.Memo,
                Type = dto.Status,
                UserName = user.RealName
            };
            ef.Add(item);
            var flag = ef.SaveChanges() > 0;


            return Output(flag, "操作成功", "操作失败");
        }

        /// <summary>
        /// 获得推荐信息
        /// </summary>
        /// <param name="certNo"></param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(List_Suggest), 200)]
        public OutputResult Suggest([FromQuery] string certNo)
        {
            var suggest = ef.Set<List_Suggest>().AsNoTracking().FirstOrDefault(x => x.CertNo == certNo.Trim());
            return Output(suggest != null, "", "", suggest);
        }

        /// <summary>
        /// 审核明细
        /// </summary>
        /// <returns></returns>
        [ProducesResponseType(typeof(Output<List<List_CheckItem>>), 200)]
        [HttpGet]
        public OutputResult CheckItems([FromQuery] string listID)
        {
            var list = ef.Set<List_CheckItem>().Where(x => x.ListID == listID).OrderByDescending(x => x.ActionTime).ToList();
            return Output(list.Count > 0, "", "", list);
        }

        #region 获得推荐分组--DIP
        /// <summary>
        /// 获得推荐病种
        /// </summary>
        /// <param name="diagnoseCode">诊断编码</param>
        /// <param name="operationCode">手术编码</param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<Sys_DIP_Para>), 200)]
        public OutputResult SuggestGroupDIP([FromQuery] string diagnoseCode, string operationCode)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }

            #region 获得主要诊断 推荐分组
            string Suborder = "";
            string Category = "";

            if (diagnoseCode != null && diagnoseCode.Length >= 5)
            {
                Suborder = diagnoseCode.Substring(0, 5);
                Category = diagnoseCode.Substring(0, 3);
            }
            var SuggestDiagnose = ef.Set<Sys_DIP_Para>().Where(x => (x.Diag_Code == Suborder && x.Disease_Type == "核心病种") || (x.Diag_Code == Category && x.Disease_Type == "综合病种")).OrderByDescending(x => x.Disease_Type).ThenByDescending(x => x.Score).ToList();
            #endregion

            #region 主要手术 推荐分组

            var results = ef.Set<Sys_DIP_Para>().Where(x => x.Oper_Code == operationCode).OrderBy(x => x.Diag_Code).ThenByDescending(x => x.Disease_Type).ThenByDescending(x => x.Score).ToList();
            List<Sys_DIP_Para> SuggestOperation = new List<Sys_DIP_Para>();
            if (results.Count < 10)
            {

                foreach (var item in results)
                {
                    var result = ef.Set<Sys_DIP_Para>().Where(x => x.Diag_Code == item.Diag_Code).OrderBy(x => x.Oper_Code).ThenByDescending(x => x.Disease_Type).ThenByDescending(x => x.Score).ToList();
                    SuggestOperation.AddRange(result);
                }
            }
            else
            {
                SuggestOperation = results;
            }
            #endregion

            return Output(true, "", "", new { SuggestDiagnose, SuggestOperation });
        }
        #endregion

        #region todo:获得推荐分组--DRG 
        /// <summary>
        /// todo:获得推荐分组--DRG 
        /// </summary>
        /// <param name="diagnoseCode">诊断编码</param>
        /// <param name="operationCode">手术编码</param>
        /// <returns></returns>
        [HttpGet]
        [ProducesResponseType(typeof(Output<Sys_DIP_Para>), 200)]
        public OutputResult SuggestGroupDRG([FromQuery] string diagnoseCode, string operationCode)
        {
            return Fail("DRG分组推荐暂无");
        }
        #endregion

        #region DIP分组器,返回病种对应的标杆信息
        /// <summary>
        /// DIP分组器,返回病种对应的标杆信息
        /// </summary>
        /// <param name="input">DIP分组器入参</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutGpResult>), 200)]
        public OutputResult DIPGroup([FromBody] InGroupPara input)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            //获得DIP分组结果
            var result = dipGrouperSvc.GroupExecue(input, tenantID);
            if (!result.Success)
            {
                return Output(false, "", "", result.msg);
            }

            #region 获得分组标杆结果
            Sys_DIP_Para? sys_DIP_Para = ef.Set<Sys_DIP_Para>().FirstOrDefault(x => x.Disease_Code == result.strResult);
            var result1 = new OutGroupBenchmark();
            result1 = _mapper.Map<OutGroupBenchmark>(sys_DIP_Para);
            if (result.dIP_Assist != null)
            {
                //查找对应的辅助目录关系
                var standardAssist = ef.Set<Sys_PolicyEnum>().FirstOrDefault(a => a.Group == "辅助目录关系"
                && a.Name3 == result.dIP_Assist.Type && a.Code2 == result.dIP_Assist.Code);
                if (standardAssist == null)
                {
                    return Fail($"缺辅助目录关系未能对应上{result.dIP_Assist.Type},{result.dIP_Assist.Code}");
                }
                result1.AssistType = result.dIP_Assist.Type;
                result1.AssistCode = standardAssist.Code1;
                result1.AssistName = standardAssist.Name1;
                result1.AssistRatio = result.dIP_Assist.Ratio;
                result1.ZGDZ = result.dIP_Assist.ZGDZ;
                result1.JMDZ = result.dIP_Assist.JMDZ;
                result1.ZGFFBZ = result.dIP_Assist.ZGFFBZ;
                result1.JMFFBZ = result.dIP_Assist.JMFFBZ;
                result1.LJFY = result.dIP_Assist.LJFY;
                result1.HighMag = result.dIP_Assist.HighMag;
                result1.LowMag = result.dIP_Assist.LowMag;
                result1.ZYTSBGZ = result.dIP_Assist.ZYTSBGZ;
            }
            #endregion

            var dipResult = _mapper.Map<OutGpResult>(result1);

            dipResult = CalcGroupBenchmark(input, dipResult, result1);

            return Output(true, "", "", dipResult);
        }
        #endregion

        #region DRG分组器,返回病种对应的标杆信息
        /// <summary>
        /// DRG分组器,返回病种对应的标杆信息
        /// </summary>
        /// <param name="input">分组器入参</param>
        /// <returns></returns>
        [HttpPost]
        [ProducesResponseType(typeof(Output<OutGpResult>), 200)]
        public OutputResult DRGGroup([FromBody] InGroupPara input)
        {
            string? tenantID = HttpContext.Request.Headers["TenantID"];
            if (string.IsNullOrEmpty(tenantID))
            {
                return Fail("缺少租户ID");
            }
            //获得DIP分组结果
            var result = drgGrouperSvc.GroupExecue(input, tenantID);

            if (!result.Success)
            {
                return Output(false, "", result.msg, result);
            }

            //根据drg结果获得标杆信息
            var para = ef.Set<Sys_DRG_Para>().SingleOrDefault(x => x.DRG_Code == result.strResult);
            var result1 = _mapper.Map<OutGroupBenchmark>(para);
            var drgResult = _mapper.Map<OutGpResult>(result1);
            drgResult = CalcGroupBenchmark(input, drgResult, result1);

            return Output(true, "", "", drgResult);

        }
        #endregion

        #region 私有方法
        #region  根据社保类型 计算分组标杆值
        /// <summary>
        /// 根据社保类型 计算分组标杆值
        /// </summary>
        /// <param name="outGpResult"></param>
        /// <param name="insuedType"></param>
        /// <returns></returns>
        private OutGpResult CalcGroupBenchmark(InGroupPara input, OutGpResult outGpResult, OutGroupBenchmark outGroupBenchmark)
        {
            #region  获得当前的点值，付费标准，费用结余
            if (input.insuedType == 1)
            {
                outGpResult.point = outGroupBenchmark.ZGDZ;
                outGpResult.benchmark = outGroupBenchmark.ZGFFBZ;
            }
            else if (input.insuedType == 2)
            {
                outGpResult.point = outGroupBenchmark.JMDZ;
                outGpResult.benchmark = outGroupBenchmark.JMFFBZ;
            }
            else
            {
                outGpResult.point = 0;
                outGpResult.benchmark = 0;
            }

            //费用结余
            outGpResult.balance = outGpResult.benchmark - input.totalCost;
            outGpResult.totalCost = input.totalCost;
            outGpResult.inDays = input.Days;
            outGpResult.insuedType = input.insuedType;
            #endregion

            #region 计算倍率
            if (outGpResult.benchmark == 0)
            {
                outGpResult.rate = 0;
            }
            else
            {
                outGpResult.rate = input.totalCost / outGpResult.benchmark;
            }
            if (outGpResult.rate >= outGroupBenchmark.HighMag)
            {
                outGpResult.rateDes = "高倍率";
            }
            else if (outGpResult.rate < outGroupBenchmark.LowMag)
            {
                outGpResult.rateDes = "低倍率";
            }
            else
            {
                outGpResult.rateDes = "正常";
            }
            #endregion

            #region 分组名称，编码
            if (!string.IsNullOrEmpty(outGroupBenchmark.AssistCode))
            {
                outGpResult.code = outGroupBenchmark.Disease_Code + "_" + outGroupBenchmark.AssistCode;
                outGpResult.name = outGroupBenchmark.Disease_Name;
                outGpResult.assistName = outGroupBenchmark.AssistName;
            }
            else
            {
                outGpResult.code = outGroupBenchmark.Disease_Code;
                outGpResult.name = outGroupBenchmark.Disease_Name;
            }
            #endregion

            return outGpResult;
        }
        #endregion
        #endregion

    }
}
